消息隊列 - RabbitMQ

陳柏仁/

2023-09-22

/
173 views
message queue rabbitmq
在前幾篇文章中,我介紹了消息隊列及其它第三方消息隊列服務。今天,我將介紹另一個第三方消息隊列服務 - RabbitMQ。

前言

在前幾篇文章中,我介紹了消息隊列及其它第三方消息隊列服務。今天,我將介紹另一個第三方消息隊列服務 - RabbitMQ。

RabbitMQ 的起源

RabbitMQ 最初是由 Rabbit 科技有限公司開發,2010 年被 VMware 旗下的 SpringSource 收購,並在 2013 年轉交由 VMware 旗下的子公司 GoPivotal 管理。

RabbitMQ

RabbitMQ 是一個使用 Erlang 語言開發的開源訊息代理(message broker)軟體,可作為訊息傳遞的中間件,為應用程式提供一個發送和接收訊息的通用平台。

RabbitMQ 的組成

RabbitMQ 使用 AMQP(Advanced Message Queuing Protocol)0-9-1 協議,主要由以下幾個要素與步驟傳送訊息:

  1. 生產者(Producer): 生產者創建訊息,並把消息發佈到交換機中
  2. 交換機(Exchange): 用於接收來自生產者的消息並依規則將其路由到一個或多個隊列
  3. 綁定(Binding): 將交換機與隊列之間建立關聯規則,定義交換機如何將訊息路由到特定隊列
  4. 隊列(Queue): RabbitMQ 中的核心元件,用於儲存訊息,暫時儲存生產者發送的訊息,直到消費者訂閱並處理它們。
  5. 消費者(Consumer): 消費者訂閱主題,獲取並處理訊息

message queue rabbitmq flow

除了上面提到的幾個主要成份外,在實務操作上仍會遇到其他實體與概念:

  • 代理者(Broker): 接收和分發訊息的應用程式,RabbitMQ server 就是一個訊息代理(message Broker)
  • 虛擬主機(Virtual host): 爲了在一個單獨的代理上實現多個隔離的環境(用戶、用戶組、交換機、隊列 等),AMQP 提供了一個虛擬主機(virtual hosts - vhosts)的概念
  • 連線(Connection): 生產者/消費者與代理者(RabbitMQ)之間的 TCP 連線
  • 通道(Channel): 通道是在連線內部建立的虛擬連接,其設計目的是減少作業系統 TCP 連線的成本,通常每個線程會建立單獨的通道進行通訊

其完整結構如下圖所示:

message queue rabbitmq overview

RabbitMQ 交換機的類型

RabbitMQ 的交換機有以下幾種類型:

  • Direct: 將訊息直接路由到與 Routing Key 相同的隊列。
  • Topic: 將訊息路由到與 topic 通配符匹配的隊列。
  • Fanout: 將訊息廣播到所有綁定的隊列。
  • Headers: 根據訊息的 header 屬性進行路由。

amqp exchange

RabbitMQ 的特性與優點

RabbitMQ 具有以下特性與優點:

有效的訊息交付 在 RabbitMQ 應用程式中,生產者直接推送消息給消費者,這表示生產者知道用戶端是否接收了訊息。這適用於需要特定順序和交付保證的場景。

靈活的路由 RabbitMQ 支援複雜靈活的路由配置,包括 Direct、Topic、Fanout、Headers 等交換機類型,交換機根據規則將消息路由到一個或多個隊列,消費者可以選擇訂閱特定的隊列,以接收其關注的消息。

可設置消息存活時間(TTL)及死信處理 使用者可以在 RabbitMQ 代理程式上設置消息存活時間,以移除不需要的訊息。同時,可以進行死信處理或異常重試等操作。。

可設置消息優先級 使用者可以在 RabbitMQ 代理程式上設置訊息的優先順序,使代理程式優先處理較高優先順序的訊息,而不是按照先進先出的順序。

支援多種程式語言 RabbitMQ 提供多種客戶端庫,支援多種程式語言,如 Java、Python、.NET、Ruby、Javascript 等,讓開發人員可以使用自己熟悉的語言與 RabbitMQ 互動並集成到各種應用程式中。

支援多種通訊協定 RabbitMQ 預設使用 AMQP 協議,並支援多種訊息傳遞協定和串流媒體,開發人員可以將其用於需要與舊式通訊協定(例如 MQTT 或 STOMP)向下相容的客戶端應用程式。

輕量級設計,提供彈性部署 RabbitMQ 是輕量級的,易於在有限資源下部署。它也支援叢集部署,通過增加更多節點來擴展訊息通訊的吞吐量,實現高可用性和高效能。

RabbitMQ 的應用場景

由於 RabbitMQ 透過推送將訊息傳送給消費者,並支援確認機制以確保訊息傳送,因此它常被金融部門或其他重視交付保證的推播系統所使用。例如,Robinhood(股票交易平台)使用 RabbitMQ 進行微服務之間的訊息傳遞,一些銀行也使用它來推送交易訊息至應用程式。

此外,由於其具有靈活的路由功能,適用於需要模糊需求或複雜路由場景的客戶端。例如,Reddit(美國 PTT)論壇包含各種不同的討論主題,它們可以根據不同的標準進行路由,從而輕鬆地將訊息傳遞到正確的隊列。

公司案例分享

我們團隊主要開發資料採集與監視系統(SCADA)、任務管理系統等專案。在實際應用中,我們使用 RabbitMQ 作為通知系統與各服務之間的中介軟體。當某項數據達到標準或工單進入某個生產節點時,各服務將訊息推送到 RabbitMQ,並通過 SMS、Email、APP 推播等方式發送給使用者,以達到通知和警報的目的。

我們利用 RabbitMQ 的特性,實現以下目標:

  • 通過控制訊息時序,實現異常延時重試。
  • 優先排序需要緊急處理的訊息。
  • 設置 prefetch limit 以避免資源消耗。

結論

相對於 Apache Kafka,RabbitMQ 在路由設置、程式語言支持和通訊協定上具有更多選擇。它的設計也較輕量且易於上手,適用於需要較高靈活性的中小型專案。而 Apache Kafka 則具有高吞吐、低延遲、高可擴展性和高可用性等優勢,適用於大數據實時計算和日誌監控等場景,因此被許多大型公司採用。

在選擇工具時,應該了解工具的特性,並根據公司業務需求和專案規模進行選擇,以確保選擇最適合的工具,避免重複造輪子。

參考資料